package com.crm.customers.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.crm.customers.dao.CommissionCustomerDao;
import com.crm.customers.dao.ContractDao;
import com.crm.customers.dao.ContractMoneylogDao;
import com.crm.customers.dao.ContractPerformanceDao;
import com.crm.customers.dao.ContractUpdateHistoryDao;
import com.crm.customers.dao.CustomerDao;
import com.crm.customers.model.CommissionCustomer;
import com.crm.customers.model.Contract;
import com.crm.customers.model.ContractMoneylog;
import com.crm.customers.model.ContractPerformance;
import com.crm.customers.model.ContractUpdateHistory;
import com.crm.customers.model.CustomerInfo;
import com.crm.customers.service.ApproveItemService;
import com.crm.customers.service.ContractFilesService;
import com.crm.customers.service.ContractMoneylogService;
import com.crm.customers.service.ContractPerformanceService;
import com.crm.customers.service.ContractService;
import com.crm.customers.service.ContractUpdateHistoryService;
import com.crm.sys.dao.ApproveConfigureDao;
import com.crm.sys.model.ApproveConfigure;
import com.crm.util.Constants;

@Service("contractUpdateHistoryService")
public class ContentUpdateHistoryServiceImpl implements ContractUpdateHistoryService {
	
	@Autowired
	private ContractUpdateHistoryDao contractUpdateHistoryDao;
	@Autowired
	private ApproveConfigureDao approveConfigureDao;
	@Autowired
	private ApproveItemService approveItemService;
	@Autowired
	private ContractService contractService;
	@Autowired
	private ContractDao contractDao;
	@Autowired
	private ContractPerformanceDao contractPerformanceDao;
	@Autowired
	private ContractMoneylogService contractMoneylogService;
	@Autowired
	private CustomerDao customerDao;
	@Autowired
	private CommissionCustomerDao commissionCustomerDao;
	@Autowired
	private ContractMoneylogDao contractMoneylogDao;
	@Autowired
	private ContractPerformanceService contractPerformanceService;
	@Autowired
	private ContractFilesService contractFilesService;
	
	
	@Override
	public int insertHistyoryAndApprove(ContractUpdateHistory cuh) throws Exception {
		
		
		int result = 0;
		
		//将审批设为审批中
		cuh.setAppstate(Constants.ApproveState.ONE);
		//保存修改记录
		cuh = contractUpdateHistoryDao.insertHistory(cuh);
		
		//添加审批
		if (cuh.getId() != null && cuh.getId() > 0) {
			
			/*
			 * 审批内容id(fkid)存合同修改记录表id
			 * 审批类型(type)存4合同修改申请
			 * 审批名称:xx申请修改合同
			 * urlid存合同修改记录表id
			 * 状态:审批中
			 * */
			
			//判断是什么修改
			String cntype = "合同";
			if (cuh.getType() == 2) {
				cntype = "收款";
			} else if (cuh.getType() == 3) {
				cntype = "付款";
			} else {
				cntype = "合同";
			}
			
			Long urlId = cuh.getId();
			String approveCode = Constants.ApproveCode.CONHISTORY;
			ApproveConfigure  cig = approveConfigureDao.selectByPrimaryKey(approveCode);
			approveItemService.saveApprove(cig, urlId, urlId, cuh.getCreateuser(), cuh.getCreateuserName()+cntype);
			result = 1;
		}
		
		return result;
	}


	@Override
	public ContractUpdateHistory getCUHByParams(ContractUpdateHistory cuh) {
		return contractUpdateHistoryDao.getCUHByParams(cuh);
	}


	@Override
	public int updateHistyory(ContractUpdateHistory cuh) {
		
		
		//2017/12/5
		/*
		 * 现在有一个问题啊，如果我合同审批通过了，款也回了，结果要换一个人才证书，或者人才正式不要了
		 * 但是这个人才有垫款啊，而且垫款也已经给消了啊...
		 * 那只有把这个人的垫款再给放出来，然后看看新增的人有没有垫款，能不能消掉
		 * */
		
		//首先,更新记录状态
		cuh = contractUpdateHistoryDao.updateHistory(cuh);
		
		//再判断审批状态,是否通过审批
		if (cuh.getAppstate() == 2) {
			//通过审批,更改合同内容
			//判断是什么类型的更新1合同 2收款 3付款
			if (cuh.getType() == 1) {
				/*
				 * 合同更新
				 * 合同更新可能涉及到业绩的重新计算
				 * 人才合同的对比修改
				 * */
				
				//修改后的合同
				Contract newc = JSON.parseObject(cuh.getContent(), Contract.class);
				//根据合同id获取修改前的合同
				Contract oldc = new Contract();
				oldc.setId(newc.getId());
				oldc = contractService.getContractInfo(oldc);
				//因为不知道是否增加或减少了人才合同,所以要做一个对比,要知道合同id(id)还有客户id(cusid)
				//将修改前的客户id和修改后的客户id作为key分别存入map中
				Map<String, Contract> newmap = new HashMap<String, Contract>();
				for (Contract c : newc.getSublist()){
					newmap.put(c.getCusid()+"-"+c.getIsadditional(), c);
				}
				Map<String, Contract> oldmap = new HashMap<String, Contract>();
				for (Contract c : oldc.getSublist()){
					oldmap.put(c.getCusid()+"-"+c.getIsadditional(), c);
				}
				//要相互比较两个集合,相同的key就是修改,old有的new没有的就是删除,new有的old没有的就是新增
				//先比较相同的和需要删除的
				//创建一个迭代器
				Iterator<String> keys = oldmap.keySet().iterator();
				while(keys.hasNext()){
		            String key = keys.next();
		            if (newmap.containsKey(key)){
		            	//含有,修改合同
		            	Contract c = newmap.get(key);
		            	c.setId(oldmap.get(key).getId());
		            	contractService.updateContract(c);
		            } else {
		            	Contract c = oldmap.get(key);
		            	c.setId(oldmap.get(key).getId());
		            	c.setIsdel(1);
		            	contractService.updateContract(c);
		            	//没有,删除合同
		            	//2017/12/5 删除之前先看看这孩子可有垫款，回来垫款消了，又没用到这人，那不亏了。
		            	//需要的几个条件：合同id，人才id
		            	ContractMoneylog cml = new ContractMoneylog();
		            	cml.setContractid(oldmap.get(key).getId());
		            	cml.setCusid(oldmap.get(key).getCusid());
		            	//contractMoneylogService.addOrCleanAdvanceMoneyLog(cml, 0);
		            	//把垫款都找回来
		            	contractMoneylogDao.addAdvanceMoneyLog(cml);
		            }
		        }
				keys = newmap.keySet().iterator();
				while(keys.hasNext()){
					String key = keys.next();
					if (!oldmap.containsKey(key)){
						//没有,新增合同
						Contract c = newmap.get(key);
						//设置为待上传合同
						if (c.getTotalamount() == 0){
							int count = contractFilesService.getFileCountByConid(c.getId());
							if(count<1) {
								c.setState(Constants.ContactsState.SIX);
							}else {
								c.setState(Constants.ContactsState.EIG);
							}
						
						} else {
							c.setState(Constants.ContactsState.TOW);
						}
						c.setPid(newc.getId());
						c.setBill(0);
						c.setType(0);
						c.setServicecharge(0);
						c.setIscomplete(0);
						c = contractDao.insert(c);
						if(c!=null&&c.getId()!=null){
							//保存完合同，更改客户到期时间
							CustomerInfo ci = new CustomerInfo();
							ci.setId(c.getCusid());
							ci.setEndtime(contractDao.selectByPrimaryKey(c).getEndtime());
							//更新用户信息
							customerDao.updateCustomerInfo(ci);
							//2017/6/23新增代办绑定,合同添加完成后,查询有没有设置代办,有的话绑定合同
							CommissionCustomer comcus = new CommissionCustomer();
							comcus.setCusid(ci.getId());
							List<CommissionCustomer> commlist = commissionCustomerDao.getCCInfoByParams(comcus);
							if (commlist != null && commlist.size() > 0) {
								for (CommissionCustomer cocu : commlist) {
									cocu.setConid(newc.getId());
									cocu.setIsdel(0);
									commissionCustomerDao.updateCCinfo(cocu);
								}
							}
						}
					}
				}
				if (newc.getOthermoney() == null) {
					newc.setOthermoney(0);
				}
				//2017/12/5
				/*
				 * 因为合同中的人员发生了变动，所以要看一下合同中的人员是不是有垫款可以被消除
				 * */
				ContractMoneylog appcml = new ContractMoneylog();
				appcml.setContractid(newc.getId());  //合同id
				appcml.setApprovalstatus(Constants.ApproveState.TOW); //已通过审核
				//第一步：获取现在可以使用的回款金额（已通过审批的总回款金额-该合同下人才合同付款类型是预付款的记录）
				Integer approvedBackMoney = contractMoneylogDao.getAllApprovedMoney(appcml);
				Integer approvedAdvanceMoney = contractMoneylogDao.getAllApprovedAdvanceMoney(appcml);
				if (approvedBackMoney == null) {
					approvedBackMoney = 0;
				}
				if (approvedAdvanceMoney == null) {
					approvedAdvanceMoney = 0;
				}
				//获取当前可使用的回款金额，如果还有余额，消垫款，如果没有，那就跳过
				if (approvedBackMoney > approvedAdvanceMoney) {
					Integer outMoney = approvedBackMoney-approvedAdvanceMoney;
					//第二步，获取人才合同中符合条件的已有的未绑定合同的垫款记录列表
					List<ContractMoneylog> approvedAdvanceList = contractMoneylogDao.getAllApproveAdvanceList(appcml);
					//第三步：循环，与当前可有金额比较，看是否可以消除垫款
					for (ContractMoneylog forcml : approvedAdvanceList) {
						//先判断金额是否大于垫款金额
						if (outMoney >= forcml.getTotalamount()) {
							//消除垫款
							//获取人才合同
							Contract scon = new Contract();
							scon.setCusid(forcml.getCusid());
							scon.setPid(newc.getId());
							scon = contractDao.getSonContractByParams(scon);
							if (forcml.getTotalamount() >= scon.getTotalamount()){
								
								int count = contractFilesService.getFileCountByConid(scon.getId());
								if(count<1) {
									scon.setState(Constants.ContactsState.SIX);
								}else {
									scon.setState(Constants.ContactsState.EIG);
								}
							
							} else if (scon.getTotalamount() == 0) {
								//还有一个条件，如果人才证书价格为0改变合同状态为付款完成
								int count = contractFilesService.getFileCountByConid(scon.getId());
								if(count<1) {
									scon.setState(Constants.ContactsState.SIX);
								}else {
									scon.setState(Constants.ContactsState.EIG);
								}
							} else {
								scon.setState(Constants.ContactsState.FOUR);
							}
							//更新合同
							contractDao.updateByPrimaryKeySelective(scon);
							//将这笔垫款消除
							forcml.setContractid(scon.getId());
							contractMoneylogService.updateContractMoneylog(forcml);
							//减去垫款
							outMoney = outMoney - forcml.getTotalamount();
						}
					}
				}
				//再修改主合同
				contractService.updateContract(newc);
				Contract upc = contractService.getContractInfo(newc);
				
				
				//查看有没有业绩记录,如果有业绩记录 删除业绩记录 重新计算业绩
				List<ContractPerformance> cpflist = contractPerformanceDao.checkIsExist(upc.getId());
				//一般都是回款时间作为业绩计算的时间
				
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
				String arrivetime = sdf.format(new Date());
				
				if (cpflist.size() > 0) {
					//
					arrivetime = cpflist.get(0).getCreatedate();
					//说明有业绩记录,要把原先的业绩记录删除,再重新添加业绩记录
					for (ContractPerformance cpf : cpflist) {
						cpf.setIsdel(1);
						contractPerformanceDao.updataContractPerformance(cpf);
					}
					//要获取已收款价格,总服务费还有合同类别
					Integer totalmoney = upc.getTotalmoney();
					Integer servicecharge = newc.getServicecharge();
					
					if (totalmoney != null && servicecharge != null && totalmoney >= servicecharge && upc.getType() == 1 && servicecharge > 0) {
						contractPerformanceService.addContractPerformance(arrivetime, newc);
					}
					
				} else {
					//说明没有业绩记录,看是否符合添加业绩记录的条件
					Integer totalmoney = upc.getTotalmoney();
					Integer servicecharge = newc.getServicecharge();
					if (totalmoney != null && servicecharge != null && totalmoney >= servicecharge && upc.getType() == 1 && servicecharge > 0) {
						//可以计算业绩，查最后一次回款的arrivetime
						String arrivesign = contractMoneylogDao.getLastBackMoneyTime(newc.getId());
						if (arrivesign != null) {
							arrivetime = arrivesign;
						}
						contractPerformanceService.addContractPerformance(arrivetime, newc);
					}
				}
			} else if(cuh.getType() == 2) {
				//收款更新 直接更新
				ContractMoneylog cml = JSON.parseObject(cuh.getContent(), ContractMoneylog.class);
				cml.setState(1);
				contractMoneylogService.updateContractMoneylog(cml);
			} else {
				//付款更新 直接更新
				ContractMoneylog cml = JSON.parseObject(cuh.getContent(), ContractMoneylog.class);
				cml.setState(1);
				contractMoneylogService.updateContractMoneylog(cml);
			}
		} else {
			//未通过审批,什么都不操作 
		}
		
		return 1;
	}


	@Override
	public int checkHistoryIsExist(ContractUpdateHistory cuh) {
		return contractUpdateHistoryDao.checkHistoryIsExist(cuh);
	}

}
